using System;
using System.Collections.Generic;
using System.Text;

namespace Scheduler
{

    /*
     * An object of this class holds information on the schedule 
     * of a certain room.
     * These information are as follows:
     * Name of the room (String room)
     * The list of 7 daily schedules representing a week (DailySched[] week)
     */
    public class Room
    {
        private String name;
        private DailySched[] week;
        private int scheduleID;

        public Room()
        {
            name = "";
            week = new DailySched[7];
            scheduleID = -1;
            for (int i = 0; i < week.Length; i++)
                week[i] = new DailySched(getDayForIndex(i));
        }
        public Room(String roomName)
        {
            name = roomName;
            week = new DailySched[7];
            scheduleID = -1;
            for (int i = 0; i < week.Length; i++)
                week[i] = new DailySched(getDayForIndex(i));
        }
        public Room(Database db, String roomName)
        {
            name = roomName;
            Room temp = db.readRoom(roomName);
            this.WeekSchedule = temp.WeekSchedule;
            this.ScheduleID = temp.ScheduleID;
        }

        public String Name
        {
            get { return name; }
            set { name = String.Copy(value); }
        }

        public DailySched[] WeekSchedule
        {
            get { return week; }
            set { week = value; }
        }
        public int ScheduleID
        {
            get { return scheduleID; }
            set { scheduleID = value; }
        }

        /*
         * This function adds the information of a given RMT into the 
         * rooms schedule
         * It finds out the day RMT is available one by one and calls 
         * a function from DailySched class to fill out the relevant 
         * scheduling slots for that day. It also calls function to 
         * update the database as well.
        */
        public Boolean addRmtSched(Database db, RMT rmt, TimeSlot curTS)
        {
            
            int index;
            index = -1;
            String curDay = curTS.StartTime.DayOfWeek.ToString();
            index = getIndexForDay(curDay);

            if (index == -1)
            {
                throw new Exception("The day is not valid: " + curDay);
            }

            if (week[index].addRmtSched(db, rmt.Name, curTS))
            {
                this.ScheduleID = db.writeSchedule(this.ScheduleID, week, index);
                return true;
            }
            return false;
        }

        /*
         * This method tries to book an appointment based on the information 
         * taken as parameter.
         * Returns true on success and false otherwise.
         * For more detail please refer to the comments in the body of this method.
         * It also calls some functions to update the database as well.
         */
        public Boolean bookAppointment(Database db, String rmtName, String custName, String therName,
                                          TimeSlot desiredTS)
        {
            int index;
            index = -1;
            String curDay = desiredTS.StartTime.DayOfWeek.ToString();
            bool success = false;

            //Find the index that corresponds to the curDay
            index = getIndexForDay(curDay);

            if (index == -1)
            {
                throw new Exception("The day is not valid: " + curDay);
            }

            //Call DailySched.bookAppoitment to continue the booking procedure.
            success = week[index].bookAppointment(db, rmtName, custName, therName, desiredTS);

            if (success)
            {
                this.ScheduleID = db.writeSchedule(this.ScheduleID, week, index);
            }

            return success;
        }


        /*
         * This method tries to remove the appointment which had been 
         * previously set for the day that corresponds to TimeSlot desiredTS.
         * Returns true on success and false otherwise.
         */
        public Boolean removeAppointment(Database db, TimeSlot desiredTS)
        {
            int index;
            index = -1;
            String curDay = desiredTS.StartTime.DayOfWeek.ToString();
            index = getIndexForDay(curDay);
            if (index == -1)
            {
                throw new Exception("The day is not valid: " + curDay);
            }

            /* 
             * call DailySched.removeAppointment to continue the removing
             * procedure 
             */
            return (week[index].removeAppointment(db, desiredTS));
        }

        /*
        * This removes the schedule of the rmt that corresponds to 
         * remTS.
         * Returns true on success and false otherwise.
        */
        public bool removeRMTSched(Database db, RMT rmt, TimeSlot remTS)
        {
            int index;
            index = -1;
            String curDay = remTS.StartTime.DayOfWeek.ToString();
            index = getIndexForDay(curDay);
            if (index == -1)
            {
                throw new Exception("The day is not valid: " + curDay);
            }

            /* 
             * call DailySched.removeAppointment to continue the removing
             * procedure 
             */
            if (week[index].removeRmtSched(db, rmt.Name, remTS))
            {
                this.ScheduleID = db.writeSchedule(this.ScheduleID, week, index);
                return true;
            }
            return false;
        }


        /*
         * This function takes a String "dayName" and returns the 
         * relevant int "index" which corresponds to the place of
         * that day in the week array.
        */
        private static int getIndexForDay(String dayName)
        {
            if (dayName == "Monday")
                return 0;
            if (dayName == "Tuesday")
                return 1;
            if (dayName == "Wednesday")
                return 2;
            if (dayName == "Thursday")
                return 3;
            if (dayName == "Friday")
                return 4;
            if (dayName == "Saturday")
                return 5;
            if (dayName == "Sunday")
                return 6;
            else return -1;
        }

        /*
         * This function takes int "index" and returns the corresponding 
         * String "dayName" which corresponds to the place of that day in 
         * the week array.
         */
        public static String getDayForIndex(int dayIndex)
        {
            if (dayIndex == 0)
                return "Monday";
            if (dayIndex == 1)
                return "Tuesday";
            if (dayIndex == 2)
                return "Wednesday";
            if (dayIndex == 3)
                return "Thursday";
            if (dayIndex == 4)
                return "Friday";
            if (dayIndex == 5)
                return "Saturday";
            if (dayIndex == 6)
                return "Sunday";
            else return "";
        }


        /*
         * Returned String contains a detailed information on the weekly schedule 
         * of this room.
         */

        public String displayScheduleForRMTAdmin()
        {
            String weekSched = "";
            for (int i = 0; i < week.Length; i++)
            {
                weekSched = weekSched + week[i].detailedDailySchedForRMTAdmin();
            }

            return weekSched;
        }


        /*
         * Returned String contains a detailed information on the weekly schedule 
         * of this room that corresponds to the rmtName.
         * It contains Partial information(rmt names and status) otherwise.
         */
        public String displayScheduleForRMT(String rmtName)
        {
            String weekSched = "";
            for (int i = 0; i < week.Length; i++)
            {
                weekSched = weekSched + week[i].detailedDailySchedForRMT(rmtName);
            }

            return weekSched;
        }


        /*
         * Returned String contains a detailed information on the weekly schedule 
         * of this room that corresponds to the custName.
         * It contains Partial information(rmt names) otherwise.
         */
        public String displayScheduleForCustomer(String custName)
        {
            String weekSched = "";
            for (int i = 0; i < week.Length; i++)
            {
                weekSched = weekSched + week[i].detailedDailySchedForCustomer(custName);
            }

            return weekSched;
        }

        /*
         * Writes the information for this room to the database
         */
        public void writeToDatabase(Database db)
        {
            this.ScheduleID = db.writeSchedule(this.ScheduleID, this.WeekSchedule, -1);
            db.writeRoom(this);
        }
    }
}
